package com.sophialex.health.record.common.bind.swt.annotations;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.ui.part.ViewPart;

import com.sophialex.health.record.common.bind.swt.annotations.helper.ObjMaker;

public class ListPathBindToProcessor extends BindToProcesspor {

	public ListPathBindToProcessor(ViewPart view, Field f, AnnotionProcessor parent, DataBindingContext bindingContext) {
		super(view, f, parent, bindingContext);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void vadidateAnnotation() {
		if(helper.getUIPropName() == null || helper.getUIPropName().trim().length() < 1)
			throw new BadBindingException(helper.toString() + "的属性UIPropName不能为空");
		if(helper.getBeanPath() == null || helper.getBeanPath().trim().length() < 1)
			throw new BadBindingException(helper.toString() + "的属性beanPath不能为空");
	}

	@SuppressWarnings( { "unchecked", "null" })
	@Override
	protected Object getBindingBean() {
		// return super.getBindingBean();
		// Pattern p = Pattern.compile("[0-9]+");
		// String[] pathElements = helper.getBeanPath().split("\\.");
		// int i1 = 0;
		// for(; i1 < pathElements.length; i1++) {
		// if(p.matcher(pathElements[i1]).matches()) {// 数字
		// break;
		// }
		// }
		// if(i1 == pathElements.length) {
		// return super.getBindingBean();
		// }

		String[] paths = helper.getBeanPath().split("\\.");
		Object upper = view;
		Pattern np = Pattern.compile("[0-9]+");

		Class<?> geniricType = null;
		int i = 0;
		for(; i < paths.length - 1; i++) {

			if(!np.matcher(paths[i]).matches()) {

				Object tmp = getFieldValue(upper, paths[i]);
				if(tmp == null) {// 还未初始化

					Method m = null;
					Class<?> clazz = null;
					Field field = null;
					try {
						m = upper.getClass().getDeclaredMethod("get" + Character.toUpperCase(paths[i].charAt(0)) + paths[i].substring(1));
						clazz = m.getReturnType();
						if(List.class.isAssignableFrom(clazz)) {
							String gs = m.getGenericReturnType().toString();
							geniricType = Class.forName(gs.split("<")[1].split(">")[0]);
						} else {
							geniricType = null;
						}
					}
					catch(Exception e) {
						// e.printStackTrace();
					}

					// 若字段为空，为其赋新值
					if(m == null) {
						try {
							field = upper.getClass().getDeclaredField(paths[i]);
							clazz = field.getType();

							if(List.class.isAssignableFrom(clazz)) {
								String gs = field.getGenericType().toString();
								geniricType = Class.forName(gs.split("<")[1].split(">")[0]);
							} else {
								geniricType = null;
							}

						}
						catch(Exception e) {
							e.printStackTrace();
							throw new BadBindingException("beanPath配置不正确！");
						}
					}
					// Constructor<?> c = null;
					// try {
					// if(clazz.equals(List.class))
					// c = ArrayList.class.getConstructor();
					// else
					// c = clazz.getConstructor();
					// } catch (Exception e) {
					// //e.printStackTrace();
					// System.out.println(clazz.getSimpleName()+"无缺省构造函数！");
					// }
					try {
						// if(clazz.equals(int.class) ||
						// clazz.equals(Integer.class)){
						// tmp = 0;
						// }else if(clazz.equals(long.class)||
						// clazz.equals(Long.class)){
						// tmp = 0L;
						// }else{
						// tmp = c.newInstance();
						// }
						tmp = ObjMaker.getInstance(clazz).newObject();
						setFieldValue(upper, paths[i], tmp);
					}
					catch(Exception e) {
						e.printStackTrace();
					}
				} else {
					if(List.class.isAssignableFrom(tmp.getClass())) {
						try {
							Method m = upper.getClass().getDeclaredMethod("get" + Character.toUpperCase(paths[i].charAt(0)) + paths[i].substring(1));
							Class clazz = m.getReturnType();

							String gs = m.getGenericReturnType().toString();
							geniricType = Class.forName(gs.split("<")[1].split(">")[0]);

						}
						catch(Exception e) {
							e.printStackTrace();
						}
					} else {
						geniricType = null;
					}
				}
				// setFieldValue(upper, paths[i], tmp);
				upper = tmp;
			} else {// 数字
				int elementIndex = Integer.parseInt(paths[i]);
				List list = (List) upper;
				if(elementIndex > list.size()) {
					try {
						// Constructor<?> c = geniricType.getConstructor();
						ObjMaker maker = ObjMaker.getInstance(geniricType);
						int size = list.size();
						for(int ii = 0; ii < elementIndex - size; ii++) {
							list.add(maker.newObject());
						}
					}
					catch(Exception e) {

					}
				}
				upper = list.get(elementIndex - 1);
				int j = i + 1;
				for(; j < paths.length; j++) {
					if(np.matcher(paths[j]).matches())
						break;
				}
				if(j == paths.length) {
					// lastElementType = upper.getClass();
					break;
				} else {
					geniricType = null;
				}
			}
		}

		// 初始化剩余部分
		for(++i; i < paths.length - 1; i++) {
			Object tmp = getFieldValue(upper, paths[i]);
			if(tmp == null) {// 还未初始化

				Method m = null;
				Class<?> clazz = null;
				Field field = null;
				try {
					m = upper.getClass().getDeclaredMethod("get" + Character.toUpperCase(paths[i].charAt(0)) + paths[i].substring(1));
					clazz = m.getReturnType();
					if(List.class.isAssignableFrom(clazz)) {
						String gs = m.getGenericReturnType().toString();
						geniricType = Class.forName(gs.split("<")[1].split(">")[0]);
					} else {
						geniricType = null;
					}
				}
				catch(Exception e) {
					// e.printStackTrace();
				}

				// 若字段为空，为其赋新值
				if(m == null) {
					try {
						field = upper.getClass().getDeclaredField(paths[i]);
						clazz = field.getType();

						if(List.class.isAssignableFrom(clazz)) {
							String gs = field.getGenericType().toString();
							geniricType = Class.forName(gs.split("<")[1].split(">")[0]);
						} else {
							geniricType = null;
						}

					}
					catch(Exception e) {
						e.printStackTrace();
						throw new BadBindingException("beanPath配置不正确！");
					}
				}

				try {
					tmp = ObjMaker.getInstance(clazz).newObject();
					setFieldValue(upper, paths[i], tmp);
				}
				catch(Exception e) {
					e.printStackTrace();
				}
			}
		}
		Pattern p = Pattern.compile("[0-9]+");
		String[] pathElements = helper.getBeanPath().split("\\.");
		int i1 = 0;
		for(; i1 < pathElements.length; i1++) {
			if(p.matcher(pathElements[i1]).matches()) {// 数字
				break;
			}
		}
		if(i1 == pathElements.length) {
			return super.getBindingBean();
		} else
			return upper;

	}

	@Override
	protected void validatebeanPath(Class<?> parent, String curBeanPath) {
		// Pattern p = Pattern.compile("[0-9]+");
		// String[] pathElements = curBeanPath.split("\\.");
		// int i=0;
		// for(;i<pathElements.length;i++){
		// if (p.matcher(pathElements[i]).matches()) {// 数字
		// break;
		// }
		// }
		// if(i==pathElements.length){
		// super.validatebeanPath(parent, curBeanPath);
		// return;
		// }
		doValidateBeanPath(parent, curBeanPath, null);

	}

	private void doValidateBeanPath(Class<?> parent, String curBeanPath, Class<?> geniricType) {
		String[] pathElements = curBeanPath.split("\\.");
		Pattern np = Pattern.compile("[0-9]+");
		if(np.matcher(pathElements[0]).matches()) {
			String p = "";
			for(int i = 1; i < pathElements.length; i++) {
				p += "." + pathElements[i];
			}
			doValidateBeanPath(geniricType, p.substring(1), null);
			return;
		}
		Field beanField = null;
		List<Field> fs = getFields(parent, true);
		Class<?> gt = null;
		for(Field f : fs) {
			if(f.getName().equals(pathElements[0]))
				beanField = f;
		}
		if(beanField == null) {
			Method get = getMethods(parent, "get" + Character.toUpperCase(pathElements[0].charAt(0)) + pathElements[0].substring(1), true);
			if(get == null)
				throw new BadBindingException("beanPath设置有误:" + parent.getSimpleName() + "不存在名为'" + pathElements[0] + "'的字段！");
			else {
				if(List.class.isAssignableFrom(get.getReturnType())) {
					try {
						gt = Class.forName(get.getGenericReturnType().toString().split("<")[1].split(">")[0]);
					}
					catch(ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(pathElements.length == 1) {
					lastElementType = get.getReturnType();
					return;
				} else {
					String newPath = curBeanPath.substring(curBeanPath.indexOf(".") + 1);
					doValidateBeanPath(get.getReturnType(), newPath, gt);
					return;
				}
			}

		} else {
			beanField.setAccessible(true);
			if(List.class.isAssignableFrom(beanField.getType())) {
				try {
					gt = Class.forName(beanField.getGenericType().toString().split("<")[1].split(">")[0]);
				}
				catch(ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(pathElements.length == 1) {
				lastElementType = beanField.getType();
				return;
			} else {
				String newPath = curBeanPath.substring(curBeanPath.indexOf(".") + 1);
				doValidateBeanPath(beanField.getType(), newPath, gt);
				return;
			}
		}

	}

	protected void setFieldValue(Object o, String fieldName, Object value) {
		Field f = null;
		List<Field> fs = getFields(o.getClass(), true);
		for(Field f1 : fs) {
			if(f1.getName().equals(fieldName))
				f = f1;
		}
		if(f != null) {
			f.setAccessible(true);
			try {
				f.set(o, value);
			}
			catch(Exception e) {
				e.printStackTrace();
				// System.exit(-1);
			}
			return;
		}

		String name = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
		parent.out(name + "\r\n");
		Method setter = null;
		try {

			setter = o.getClass().getMethod(name, value.getClass());

		}
		catch(Exception e1) {
			e1.printStackTrace();
			// System.exit(-1);// 没办法了，退出
		}
		try {

			setter.invoke(o, value);

		}
		catch(Exception e1) {
			e1.printStackTrace();
			// System.exit(-1);
		}

	}

	@Override
	protected String getBindingBeanPath() {
		Pattern p = Pattern.compile("[0-9]+");
		String[] pathElements = helper.getBeanPath().split("\\.");
		int i = 0;
		int c = 0;
		for(; i < pathElements.length; i++) {
			if(p.matcher(pathElements[i]).matches()) {// 数字
				c = i;
			}
		}
		if(c == 0) {
			return super.getBindingBeanPath();
		}
		String path = "";
		for(int j = c + 1; j < pathElements.length; j++) {
			path += "." + pathElements[j];
		}
		// System.out.println(path.substring(1));
		return path.substring(1);
		// return helper.getBeanPath().substring(0,
		// helper.getBeanPath().lastIndexOf("."));
	}

}
